/*
 * @Author: 0x9DEFA478
 * @Date: 2021-08-17 18:20:39
 * @LastEditTime: 2021-08-18 21:14:05
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "IP_UART.h"








//dma发送完成中断调用
static void IP_UART_DMA_IRQ_tx(void* v){
  IP_UART* ip_uart;

  ip_uart=v;

  

  if(oIP_DMA_GetTC_ISR(ip_uart->Instance.DMA_Tx)){
    oIP_DMA_ClearAllBit_IFCR(ip_uart->Instance.DMA_Tx);
    ip_uart->TransmitDoneCallback(ip_uart->v);
  }else{
    for(;;){
      //出现了意外情况
    }
  }

}

//usart中断处理
static void IP_UART_IRQ(void* v){
  IP_UART* ip_uart;
  unsigned int ISR;
  unsigned int NDTR;

  ip_uart=v;

  ISR=cIP_UART_UART(ip_uart)->ISR;

  // cIP_UART_UART(ip_uart)->ICR=USART_ICR_PECF|USART_ICR_FECF|USART_ICR_NCF|USART_ICR_ORECF
  //                            |USART_ICR_IDLECF|USART_ICR_TCCF|USART_ICR_TCBGTCF|USART_ICR_LBDCF
  //                            |USART_ICR_CTSCF|USART_ICR_RTOCF|USART_ICR_EOBCF|USART_ICR_CMCF;

  if(ISR&USART_ISR_PE){
    cIP_UART_UART(ip_uart)->ICR=USART_ICR_PECF;

    ip_uart->ParityError=-1;
  }

  if(ISR&USART_ISR_IDLE){
    cIP_UART_UART(ip_uart)->ICR=USART_ICR_IDLECF;
    //IDLE中断

    cIP_UART_rxDMA(ip_uart)->CR&=~DMA_SxCR_EN;//失能DMA
    while((cIP_UART_rxDMA(ip_uart)->CR&DMA_SxCR_EN)!=0){
    }
    NDTR=cIP_UART_rxDMA(ip_uart)->NDTR;
    

    if(ip_uart->CurrentRecvBuffer==ip_uart->RecvBuffer){

      ip_uart->CurrentRecvBuffer=&((unsigned char*)ip_uart->RecvBuffer)[ip_uart->RecvBufferSize];
      cIP_UART_rxDMA(ip_uart)->M0AR=(unsigned int)ip_uart->CurrentRecvBuffer;
      cIP_UART_rxDMA(ip_uart)->NDTR=ip_uart->RecvBufferSize;

      oIP_DMA_ClearAllBit_IFCR(ip_uart->Instance.DMA_Rx);
      cIP_UART_rxDMA(ip_uart)->CR|=DMA_SxCR_EN;//使能DMA

      if(ip_uart->ParityError==0){
        ip_uart->RecvDoneCallback(ip_uart->v,ip_uart->RecvBuffer,ip_uart->RecvBufferSize-NDTR);
      }else{
        ip_uart->ParityError=0;
      }
    }else{

      ip_uart->CurrentRecvBuffer=ip_uart->RecvBuffer;
      cIP_UART_rxDMA(ip_uart)->M0AR=(unsigned int)ip_uart->CurrentRecvBuffer;
      cIP_UART_rxDMA(ip_uart)->NDTR=ip_uart->RecvBufferSize;

      oIP_DMA_ClearAllBit_IFCR(ip_uart->Instance.DMA_Rx);
      cIP_UART_rxDMA(ip_uart)->CR|=DMA_SxCR_EN;//使能DMA

      if(ip_uart->ParityError==0){
        ip_uart->RecvDoneCallback(ip_uart->v,&((unsigned char*)ip_uart->RecvBuffer)[ip_uart->RecvBufferSize],ip_uart->RecvBufferSize-NDTR);
      }else{
        ip_uart->ParityError=0;
      }
    }

  }
  if(ISR&USART_ISR_FE){
    cIP_UART_UART(ip_uart)->ICR=USART_ICR_FECF;
  }
  if(ISR&USART_ISR_ORE){
    cIP_UART_UART(ip_uart)->ICR=USART_ICR_ORECF;
  }

}

/**
 * @brief UART开始dma发送接收
 *        接收与发送开始工作 接收到数据会调用接收回调 通过 IP_UART_DMATxRx_Transmit()写入要发送的数据
 * @param ip_uart IP_UART对象
 * @param TransmitBuffer 发送缓冲区
 * @param TransmitBufferSize 发送缓冲区大小 单位:字节
 * @param RecvBuffer 接收缓冲区(同一时间只会有一半在使用)
 * @param RecvBufferSize 接收缓冲区大小 单位:字节 (建议为2的倍数 否则多出来的1字节将不使用)
 * @return 无
 */
void IP_UART_DMATxRx_Start(IP_UART* ip_uart,void* TransmitBuffer,int TransmitBufferSize,void* RecvBuffer,int RecvBufferSize){

  ip_uart->TransmitBuffer=TransmitBuffer;
  ip_uart->TransmitBufferSize=TransmitBufferSize;
  ip_uart->RecvBuffer=RecvBuffer;
  ip_uart->RecvBufferSize=RecvBufferSize/2;

  ip_uart->ParityError=0;

  ip_uart->SetIrqCallback(IP_UART_IRQ,ip_uart);
  ip_uart->Instance.DMA_Tx->SetIrqCallback(IP_UART_DMA_IRQ_tx,ip_uart);

  cIP_UART_UART(ip_uart)->CR1|=USART_CR1_PEIE|USART_CR1_IDLEIE;//使能中断
  cIP_UART_UART(ip_uart)->CR3|=USART_CR3_DMAR|USART_CR3_DMAT;//使能DMA请求


  ip_uart->CurrentRecvBuffer=ip_uart->RecvBuffer;
  cIP_UART_rxDMA(ip_uart)->PAR=(unsigned int)&cIP_UART_UART(ip_uart)->RDR;
  cIP_UART_rxDMA(ip_uart)->M0AR=(unsigned int)ip_uart->CurrentRecvBuffer;
  cIP_UART_rxDMA(ip_uart)->NDTR=ip_uart->RecvBufferSize;

  oIP_DMA_ClearAllBit_IFCR(ip_uart->Instance.DMA_Rx);
  cIP_UART_rxDMA(ip_uart)->CR|=DMA_SxCR_EN;//使能DMA

  cIP_UART_txDMA(ip_uart)->PAR=(unsigned int)&cIP_UART_UART(ip_uart)->TDR;
  cIP_UART_txDMA(ip_uart)->M0AR=(unsigned int)ip_uart->TransmitBuffer;

  cIP_UART_UART(ip_uart)->CR1|=USART_CR1_UE;
}

/**
 * @brief 获取UART发送是否完成
 * @param ip_uart IP_UART对象
 * @return 0:完成 其他:未完成
 */
int IP_UART_DMATxRx_TransmitIsDone(IP_UART* ip_uart){

  if(cIP_UART_txDMA(ip_uart)->CR&DMA_SxCR_EN){
    //dma正在传输
    return -1;
	}
	
  if(!(cIP_UART_UART(ip_uart)->ISR&USART_ISR_TXE)){
    return -1;
  }
	if(!(cIP_UART_UART(ip_uart)->ISR&USART_ISR_TC)){
		return -1;
	}
	
	return 0;
}

/**
 * @brief 发送数据 本方法适用于8bit模式 使用前应使用IP_UART_DMATxRx_SetCallback()来设置回调
 * @param ip_uart IP_UART对象
 * @return 0:成功 其他:错误
 */
int IP_UART_DMATxRx_Transmit(IP_UART* ip_uart,unsigned char* Buffer,int Length){
  unsigned char* dst;
  int i;

  if(Length>ip_uart->TransmitBufferSize){
    return -1;
  }
  if(IP_UART_DMATxRx_TransmitIsDone(ip_uart)!=0){
    return 0;
  }

  dst=ip_uart->TransmitBuffer;

  i=Length;
  while(i>0){
    i--;
    dst[i]=Buffer[i];
  }

  __DSB();
  __ISB();

  
  cIP_UART_txDMA(ip_uart)->NDTR=(unsigned int)Length;
  cIP_UART_txDMA(ip_uart)->CR|=DMA_SxCR_TCIE;//使能完成中断

  oIP_DMA_ClearAllBit_IFCR(ip_uart->Instance.DMA_Tx);
  cIP_UART_txDMA(ip_uart)->CR|=DMA_SxCR_EN;//使能DMA

}

/**
 * @brief 获取一次性最大能发送数据的大小
 * @param ip_uart IP_UART对象
 * @return 数据大小
 */
int IP_UART_DMATxRx_GetMaxTransmitSize(IP_UART* ip_uart){
  return ip_uart->TransmitBufferSize;
}